In order for client programs to choose the best data handler component for a data reference, Apple has defined some functions that allow applications to interrogate a data handler's capabilities.
The DataHGetVolumeList function allows an application to obtain a list of the volumes your data handler can support. The DataHCanUseDataRef function allows your data handler to examine a specific data reference and indicate its ability to work with the associated container. The DataHGetDeviceIndex function allows applications to determine whether different data references identify containers that reside on the same device.
By way of illustration, the Movie Toolbox uses the DataHGetVolumeList and DataHCanUseDataRef functions as follows. During startup, and whenever a new volume is mounted, the Movie Toolbox calls each data handler's DataHGetVolumeList function in order to obtain information about each handler's general capabilities. Specifically, the Movie Toolbox calls each component's GetDataHandler , DataHGetVolumeList , and CloseComponent functions.
Whenever an application opens a movie, the Movie Toolbox selects the best data handler for the movie's container. This may involve calling each appropriate data handler's DataHCanUseDataRef function (in some cases, a data handler may indicate that it does not need to examine a data reference before accessing it--see the description of the DataHGetVolumeList function for more information). For each data handler that can support the data reference (that is, has the correct component subtype value) and needs to be interrogated, the Movie Toolbox calls the component's GetDataHandler , DataHCanUseDataRef , and CloseComponent functions. Based on the resulting information, the Movie Toolbox selects the best data handler for the application.
For more information on selecting a data handler, see "Selecting a Data Handler".
In response to the DataHGetVolumeList function, your data handler component returns a list of the volumes your component can access, along with flags indicating your component's capabilities for each volume.
pascal ComponentResult DataHGetVolumeList (
DataHandler dh,
DataHVolumeList *volumeList);
In order to reduce the delay that may result from choosing an appropriate data handler for a volume, the Movie Toolbox maintains a list of data handlers and the volumes they support. The Movie Toolbox uses the DataHGetVolumeList function to build that list.
When your component receives this function, it should scan the available volumes and create a series of DataHVolumeListRecord structures--one structure for each volume your component can access. This structure is defined as follows:
typedef struct DataHVolumeListRecord {
short vRefNum; /* reference number */
long flags; /* capability flags */
} DataHVolumeListRecord, *DataHVolumeListPtr, **DataHVolumeList;
Your data handler may use any facilities necessary to determine whether it can access the volume, including opening a container on the volume. Your component should set to 1 as many of the capability flags as are appropriate for each volume. Do not include records for volumes your handler cannot support.
For example, if your component supports networked multimedia servers using a special set of protocols, your data handler should set the kDataHCanRead and kDataHCanSpecialRead flags to 1 for any volume that is on that server. In addition, if your component can write to a volume on the server, set the kDataHCanWrite and kDataHCanSpecialWrite flags to 1 (perhaps along with kDataHCanStreamingWrite ). However, your component should create entries only for those volumes that support your protocols.
It is the calling program's responsibility to dispose of the handle returned by your component.
The Movie Toolbox tracks mounting and unmounting removable volumes, and keeps its volume list current. As a result, the Movie Toolbox may call your component's DataHGetVolumeList function whenever a removable volume is mounted.
If your data handler does not process data that is stored in file system volumes, you need not support this function.
The DataHCanUseDataRef function allows your data handler to report whether it can access the data associated with a specified data reference.
pascal ComponentResult DataHCanUseDataRef (
DataHandler dh,
Handle dataRef,
long *useFlags);
Apple's standard data handler sets both the kDataHCanRead and kDataHCanWrite flags to 1 for any data reference it receives, indicating that it can read from and write to any volume.
Your component should set to 1 as many of the capability flags as are appropriate for the specified data reference. Conversely, be sure to set the flags to 0 if your component cannot support the container. For example, if your component supports networked multimedia servers using a special set of protocols, your data handler should set the kDataHCanRead and kDataHCanSpecialRead flags to 1 for any container that is on that server. In addition, if your component can write to the server, set the kDataHCanWrite and kDataHCanSpecialWrite flags to 1 (perhaps along with kDataHCanStreamingWrite ). However, your component should set the flags field to 0 for any container that is not on a server that supports your protocols.
Your data handler may use any facilities necessary to determine whether it can access the container. Bear in mind, though, that your component should try to be as quick about this determination as possible, in order to minimize the chance that the delay will be noticed by the user.
In response to the DataHGetDeviceIndex function, your data handler component returns a value that identifies the device on which a data reference resides.
pascal ComponentResult DataHGetDeviceIndex (
DataHandler dh,
long *deviceIndex);
Some client programs may need to account for the fact that two or more data references reside on the same device. For instance, this may affect storage-allocation requirements. This function allows such client programs to obtain this information from your data handler.
Your component may use any identifier value that is appropriate (as an example, Apple's HFS data handler uses the volume reference number). The client program should do nothing with the value other than compare it with other identifiers returned by your data handler component.
| Previous | Chapter Contents | Chapter Top | Next |